home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / p4 / p4-1_2a.lha / p4-1.2a / messages / systest.c < prev    next >
C/C++ Source or Header  |  1992-10-19  |  11KB  |  467 lines

  1. #include "p4.h"
  2.  
  3. extern void slave();
  4.  
  5. int main(argc,argv)
  6.      int argc;
  7.      char **argv;
  8. /*
  9.   Generic SPMD master program .. just creates environment
  10.   and then calls slave, just as the slaves do.
  11.   This probably does NOT do what U want on the iPSC.
  12. */
  13. {
  14.   p4_initenv(&argc,argv);
  15.   if (p4_get_my_id() == 0)
  16.       p4_create_procgroup();
  17.  
  18.   slave();
  19.  
  20.   p4_wait_for_end();
  21. }
  22.  
  23. #define MAX(a,b) (((a)>(b)) ? (a) : (b))
  24.  
  25. static void Hello();
  26. static void Ring();
  27. static void Stress();
  28. static void Globals();
  29. static int  GlobalReadInteger();
  30.  
  31. extern void synchronize();
  32.  
  33. void slave()
  34. /*
  35.   Test and time aspects of the system.
  36. */
  37. {
  38.   int me = p4_get_my_id();
  39.   int option;
  40.  
  41.   (void) p4_soft_errors(FALSE);  /* This should be the default */
  42.  
  43.   p4_dprintfl(00,"%d is alive on a %s\n",me,p4_machine_type());
  44.   fflush(stdout);
  45.  
  46.   while (1) {
  47.  
  48.     synchronize(1000);
  49.     /* sleep(1); */          /* To allow output to catch up */
  50.  
  51.   again:
  52.     if (me == 0) {
  53.       /* Read user input for action */
  54.       (void) printf("\nOptions: 0=quit, 1=Hello, 2=Ring, 3=Stress, ");
  55.       (void) printf("4=Globals : ");
  56.       (void) fflush(stdout);
  57.     }
  58.     option = GlobalReadInteger();
  59.     if ( (option < 0) || (option > 4) )
  60.       goto again;
  61.  
  62.     switch (option) {
  63.     case 0:
  64.       return;
  65.  
  66.     case 1:
  67.       Hello();
  68.       break;
  69.  
  70.     case 2:
  71.       Ring();
  72.       break;
  73.  
  74.     case 3:
  75.       Stress();
  76.       break;
  77.  
  78.     case 4:
  79.       Globals();
  80.       break;
  81.  
  82.     default:
  83.       p4_error("systest: invalid option", option);
  84.       break;
  85.     }
  86.   }
  87. }
  88.  
  89. static void Hello()
  90. /*
  91.   Everyone exchanges a hello message with everyone else.
  92.   The hello message just comprises the sending and target nodes.
  93. */
  94. {
  95.   int nproc = p4_num_total_ids();
  96.   int me = p4_get_my_id();
  97.   int type = 1;
  98.   int buffer[2], node, *input, length;
  99.  
  100.   if (me == 0) {
  101.     (void) printf("\nHello test ... show network integrity\n----------\n\n");
  102.     (void) fflush(stdout);
  103.   }
  104.  
  105.   for (node = 0; node<nproc; node++) {
  106.     if (node != me) {
  107.       buffer[0] = me;
  108.       buffer[1] = node;
  109.       (void) p4_sendx(type,node,(char *) buffer,sizeof buffer,P4INT);
  110.       input = (int *) NULL;
  111.       (void) p4_recv(&type, &node, (char **) &input, &length);
  112.  
  113.       if ( (input[0] != node) || (input[1] != me) ) {
  114.     (void) fprintf(stderr, "Hello: %d!=%d or %d!=%d\n",
  115.                input[0], node, input[1], me);
  116.     p4_error("Mismatch on hello process ids", node);
  117.       }
  118.  
  119.       (void) p4_dprintfl(00,"Hello from %d to %d\n", me, node);
  120.       (void) fflush(stdout);
  121.     }
  122.   }
  123. }
  124.  
  125. static void Ring()
  126.      /* Time passing a message round a ring */
  127. {
  128.   int me = p4_get_my_id();
  129.   int nproc = p4_num_total_ids();
  130.   int type = 4;
  131.   int left = (me + nproc - 1) % nproc;
  132.   int right = (me + 1) % nproc;
  133.   char *buffer;
  134.   int start, lenbuf, used, max_len, *msg, msg_len;
  135.   double rate;
  136.   p4_usc_time_t start_ustime, end_ustime, used_ustime;
  137.  
  138.   /* Find out how big a message to use */
  139.  
  140.   if (me == 0) {
  141.     (void) printf("\nRing test ... time network performance\n---------\n\n");
  142.     (void) printf("Input maximum message size: ");
  143.     (void) fflush(stdout);
  144.   }
  145.   max_len = GlobalReadInteger();
  146.   if ( (max_len <= 0) || (max_len >= 4*1024*1024) )
  147.     max_len = 512*1024;
  148.   if (me == 0)
  149.     if ( (buffer = p4_shmalloc((unsigned) max_len)) == (char *) NULL)
  150.       p4_error("Ring: failed to allocate buffer",max_len);
  151.  
  152.   type = 5;
  153.  
  154.   lenbuf = 1;
  155.   while (lenbuf <= max_len) {
  156.  
  157.     start = p4_clock();
  158.     start_ustime = p4_ustimer();
  159.     if (me == 0) {
  160.       (void) p4_send(type, left, buffer, lenbuf);
  161.       msg = (int *) NULL;
  162.       (void) p4_recv(&type, &right, (char **) &msg, &msg_len);
  163.       p4_msg_free((char *) msg);
  164.     }
  165.     else {
  166.       msg = (int *) NULL;
  167.       (void) p4_recv(&type, &right, (char **) &msg, &msg_len);
  168.       (void) p4_send(type, left, (char *) msg, msg_len);
  169.       p4_msg_free((char *) msg);
  170.     }
  171.     used = p4_clock() - start;
  172.     used_ustime = p4_ustimer() - start_ustime;
  173.  
  174.     if (used > 0)
  175.       rate = 1.0e-3 * (double) (nproc * lenbuf) / (double) used;
  176.     else
  177.       rate = 0.0;
  178.     if (me == 0)
  179.       (void) printf("len=%d bytes, used=%d ms, used_us=%d rate=%f Mb/s\n",
  180.             lenbuf, used, used_ustime, rate);
  181.     
  182.     lenbuf *= 2;
  183.   }
  184.  
  185.   if (me == 0)
  186.     (void) p4_shfree(buffer);
  187.  
  188. }
  189.  
  190. double ranf()
  191. /* Returns ran # uniform in (0,1) ... probably rather bad statistics. */
  192. {
  193.   static unsigned long seed = 54321;
  194.  
  195.   seed = seed * 1812433253 + 12345;
  196.   return (seed & 0x7fffffff) * 4.6566128752458e-10;
  197. }
  198.  
  199. static void RandList(lo, hi, list, n)
  200.      int lo, hi, *list, n;
  201. /*
  202.   Fill list with n random integers between lo & hi inclusively
  203. */
  204. {
  205.   int i, ran;
  206.   double dran;
  207.  
  208.   for (i=0; i<n; i++) {
  209.     dran = ranf();
  210.     ran = lo + (int) (dran * (double) (hi-lo+1));
  211.     if (ran < lo)
  212.       ran = lo;
  213.     if (ran > hi)
  214.       ran = hi;
  215.     list[i] = ran;
  216.   }
  217. }
  218.  
  219. static void Stress()
  220. /*
  221.   Stress the system by passing messages between a randomly selected
  222.   list of nodes
  223. */
  224. {
  225. #define N_LEN 10
  226.   static int len[N_LEN] = {0,1,2,4,8,4096,8192,16384,32768,65536};
  227.   int me = p4_get_my_id();
  228.   int nproc = p4_num_total_ids();
  229.   int zero = 0;
  230.   int type, lenbuf, i, j, from, to;
  231.   int *list_i, *list_j, *list_n;
  232.   char *buffer;
  233.   int n_stress, mod, *msg, msg_len;
  234.  
  235.   type = 6;
  236.   if (me == 0) {
  237.     (void) printf("\nStress test ... randomly exchange messages\n-----------");
  238.     (void) printf("\n\nInput no. of messages: ");
  239.     (void) fflush(stdout);
  240.   }
  241.   n_stress = GlobalReadInteger();
  242.   if ( (n_stress <= 0) || (n_stress > 100000) )
  243.     n_stress = 1000;
  244.   p4_dprintfl(00,"n_stress=%d\n",n_stress);
  245.  
  246.   lenbuf = n_stress * sizeof(int);
  247.  
  248.   if (!(buffer = p4_shmalloc((unsigned) len[N_LEN-1])))
  249.     p4_error("Stress: failed to allocate buffer", len[N_LEN-1]);
  250.  
  251.   type = 7;
  252.   if (me == 0) { /* Make random list of pairs and message lengths */
  253.     if (!(list_i = (int *) p4_shmalloc((unsigned) lenbuf)))
  254.       p4_error("Stress: failed to allocate list_i",lenbuf);
  255.     if (!(list_j = (int *) p4_shmalloc((unsigned) lenbuf)))
  256.       p4_error("Stress: failed to allocate list_j",lenbuf);
  257.     if (!(list_n = (int *) p4_shmalloc((unsigned) lenbuf)))
  258.       p4_error("Stress: failed to allocate list_n",lenbuf);
  259.  
  260.     RandList((int) 0, nproc-1, list_i, n_stress);
  261.     RandList((int) 0, nproc-1, list_j, n_stress);
  262.     RandList((int) 0, N_LEN-1, list_n, n_stress);
  263.     for (i=0; i<n_stress; i++)
  264.       list_n[i] = len[list_n[i]];
  265.     p4_broadcastx(type, (char *) list_i, lenbuf, P4INT);
  266.     p4_broadcastx(type, (char *) list_j, lenbuf, P4INT);
  267.     p4_broadcastx(type, (char *) list_n, lenbuf, P4INT);
  268.   }
  269.   else {
  270.     list_i = (int *) NULL;
  271.     (void) p4_recv(&type, &zero, (char **) &list_i, &msg_len);
  272.     list_j = (int *) NULL;
  273.     (void) p4_recv(&type, &zero, (char **) &list_j, &msg_len);
  274.     list_n = (int *) NULL;
  275.     (void) p4_recv(&type, &zero, (char **) &list_n, &msg_len);
  276.   }
  277.  
  278.   type = 8;
  279.  
  280.   j = 0;
  281.   mod = (n_stress-1)/10 + 1;
  282.   for (i=0; i < n_stress; i++) {
  283.  
  284.     from   = list_i[i];
  285.     to     = list_j[i];
  286.     lenbuf = list_n[i];
  287.  
  288.     /* P4 can send to self 
  289.     if (from == to)
  290.       continue; */
  291.  
  292.     if ( (me == 0) && (j%mod == 0) ) {
  293.       (void) printf("Stress: test=%ld: from=%ld, to=%ld, len=%ld\n",
  294.             i, from, to, lenbuf);
  295.       (void) fflush(stdout);
  296.     }
  297.  
  298.     j++;  /* Needed when skipping send to self */
  299.  
  300.     if (from == me)
  301.       (void) p4_send(type, to, buffer, lenbuf);
  302.  
  303.     if (to == me) {
  304.       msg = (int *) NULL;
  305.       (void) p4_recv(&type, &from, (char **) &msg, &msg_len);
  306.       p4_msg_free((char *) msg);
  307.       if (msg_len != lenbuf)
  308.     p4_error("Stress: invalid message length on receive",lenbuf);
  309.     }
  310.   }
  311.  
  312.   (void) p4_shfree(buffer);
  313.   if (me == 0) {
  314.     (void) p4_shfree((char *) list_n);
  315.     (void) p4_shfree((char *) list_j);
  316.     (void) p4_shfree((char *) list_i);
  317.   }
  318.   else {
  319.     (void) p4_msg_free((char *) list_n);
  320.     (void) p4_msg_free((char *) list_j);
  321.     (void) p4_msg_free((char *) list_i);
  322.   }
  323. }
  324.  
  325. static int GlobalReadInteger()
  326. /*
  327.   Process zero reads an integer from stdin and broadcasts
  328.   to everyone else
  329. */
  330. {
  331.   int value, *msg, msg_len, type=999,zero=0;
  332.  
  333.   if (p4_get_my_id() == 0) {
  334.     if (scanf("%d", &value) != 1)
  335.       p4_error("failed reading integer value from stdin", -1);
  336.  
  337.     p4_broadcastx(type, (char *) &value, sizeof value,P4INT);
  338.   }
  339.   else {
  340.     msg = (int *) NULL;
  341.     (void) p4_recv(&type, &zero, (char **) &msg, &msg_len);
  342.     value = *msg;
  343.     p4_msg_free((char *) msg);
  344.   }
  345.   return value;
  346. }
  347.  
  348. static int CompareVectors(n, a, b)
  349.      int n;
  350.      double *a, *b;
  351. /*
  352.   Return the no. of differences in two vectors allowing for
  353.   numerical roundoff.
  354. */
  355. {
  356. #define ABS(a)   (((a)>=0 ) ? (a) : -(a))
  357.   int nerrs = 0;
  358.   double diff;
  359.  
  360.   while (n--) {
  361.     diff = *a++ - *b++;
  362.     if (ABS(diff) > 1.0e-8)
  363.       nerrs++;
  364.   }
  365.   
  366.   return nerrs;
  367. }
  368.  
  369. static void Globals()
  370. /*
  371.   Test out functioning of the global operations.
  372. */
  373. {
  374.   int nproc = p4_num_total_ids();
  375.   int me = p4_get_my_id();
  376.   int n, i, start, used, nerrs;
  377.   double *a, *b, rate;
  378.  
  379. #define DO(string, op) \
  380.   start = p4_clock(); \
  381.   if (p4_global_op(33, (char *) a, n, sizeof(double), op, P4DBL)) \
  382.     p4_error("p4_global_op failed",n); \
  383.   used = p4_clock()-start; \
  384.   rate = (used>0) ? n/(1.0e+3 * used) : 0.0; \
  385.   nerrs = CompareVectors(n, a, b); \
  386.   if (me == 0) \
  387.     (void) printf("%s, len=%d, used=%d ms, rate=%f Mop/s, nerrs=%d\n",\
  388.                    string, n, used, rate, nerrs);
  389.  
  390.   if (me == 0) {
  391.     (void) printf("\nGlobal operations test\n----------------------");
  392.     (void) printf("\n\nInput vector length ");
  393.     (void) fflush(stdout);
  394.   }
  395.   n = GlobalReadInteger();
  396.   if ( (n < 0) || (n > 1000000) )
  397.     n = 1000;
  398.  
  399.   if (!(a = (double *) p4_shmalloc((unsigned) (n*sizeof(double)))))
  400.     p4_error("failed to create work space (a)",n);
  401.   if (!(b = (double *) p4_shmalloc((unsigned) (n*sizeof(double)))))
  402.     p4_error("failed to create work space (b)",n);
  403.  
  404.   /* Summation */
  405.  
  406.   for (i=0; i<n; i++) {
  407.     a[i] = i+me;
  408.     b[i] = nproc*i + (nproc*(nproc-1))/2;
  409.   }
  410.   DO("Summation", p4_dbl_sum_op);
  411.  
  412.   /* Maximum */
  413.  
  414.   for (i=0; i<n; i++) {
  415.     a[i] = i+me;
  416.     b[i] = i+nproc-1;
  417.   }
  418.   DO("Maximum", p4_dbl_max_op);
  419.  
  420.   /* Abs Maximum */
  421.  
  422.   for (i=0; i<n; i++) {
  423.     a[i] = i+me - n/2;
  424.     b[i] = MAX(n/2-i, i+nproc-1-n/2);
  425.   }
  426.   DO("Abs Maximum", p4_dbl_absmax_op);
  427.  
  428.   /* Tidy up */
  429.  
  430.   p4_shfree((char *) b);
  431.   p4_shfree((char *) a);
  432. }
  433.  
  434.  
  435. void synchronize(type)
  436.      int type;
  437. /*
  438.   Processes block until all have checked in with process 0
  439.   with a message of specified type .. a barrier.
  440. */
  441. {
  442.   int me = p4_get_my_id();
  443.   int nproc = p4_num_total_ids();
  444.   int zero = 0;
  445.   int *msg;
  446.   int msg_len, node, dummy = type;
  447.  
  448.   if (me == zero) {
  449.     for (node=1; node<nproc; node++){       /* Check in */
  450.       msg = (int *) NULL;
  451.       if (p4_recv(&type, &node, (char **) &msg, &msg_len))
  452.     p4_error("synchronize: recv 1 failed", (int) msg);
  453.       p4_msg_free((char *) msg);
  454.     }
  455.     if (p4_broadcast(type, (char *) &dummy, sizeof dummy))
  456.       p4_error("synchronize: broadcast failed",type);
  457.   }
  458.   else {
  459.     if (p4_send(type, zero, (char *) &me, sizeof me))
  460.       p4_error("synchronize: send failed", type);
  461.     msg = (int *) NULL;
  462.     if (p4_recv(&type, &zero, (char **) &msg, &msg_len))
  463.       p4_error("synchronize: recv 2 failed", (int) msg);
  464.     p4_msg_free((char *) msg);
  465.   }
  466. }    
  467.